home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / PROLOG / HUMBOLT / HUMBOLTS / _files / _humboltsr / UNI._c < prev    next >
Text File  |  1990-12-08  |  14KB  |  494 lines

  1. /***************************************************
  2. ****************************************************
  3. **                                                **
  4. **  HU-Prolog     Portable Interpreter System     ** 
  5. **                                                **
  6. **  Release 1.62   January  1990                  **
  7. **                                                **
  8. **  Authors:      C.Horn, M.Dziadzka, M.Horn      **
  9. **                                                **
  10. **  (C) 1989      Humboldt-University             **
  11. **                Department of Mathematics       **
  12. **                GDR 1086 Berlin, P.O.Box 1297   **
  13. **                                                **
  14. ****************************************************
  15. ***************************************************/
  16.  
  17. #include "systems.h"
  18. #include "types.h"
  19. #include "errors.h"
  20. #include "atoms.h"
  21. #include "manager.h"
  22.  
  23. /* 
  24.  
  25. When backtracking occurs, it is necessary to undo the variable bindings
  26. introduced during execution of the failed clauses.  For this purpose,
  27. certain critical bindings are recorded on an auxiliary stack called the
  28. trail.  The critical bindings are those involving variables created in
  29. environments older than choicepoint: those newer than choicepoint will
  30. disappear when the stacks contract.
  31.  
  32. */
  33.  
  34. #if P8000
  35. #define reg1 register
  36. #define reg2 register
  37. #define reg3 register
  38. #define reg4 register
  39. #define reg5 register
  40. #define reg6 register
  41. #endif
  42.  
  43. #if RISCOS
  44. #define reg1 register
  45. #define reg2 register
  46. #define reg3 register
  47. #define reg4 register
  48. #endif
  49.  
  50.  
  51. #if MSC 
  52. #define reg1 register
  53. #define reg2 register
  54. #endif
  55.  
  56. #ifndef reg1
  57. #define reg1 
  58. #endif
  59. #ifndef reg2
  60. #define reg2 
  61. #endif
  62. #ifndef reg3
  63. #define reg3 
  64. #endif
  65. #ifndef reg4
  66. #define reg4 
  67. #endif
  68. #ifndef reg5
  69. #define reg5 
  70. #endif
  71. #ifndef reg6
  72. #define reg6 
  73. #endif
  74. #ifndef reg7
  75. #define reg7
  76. #endif
  77. #ifndef reg8
  78. #define reg8
  79. #endif
  80. #ifndef reg9
  81. #define reg9
  82. #endif
  83. #ifndef reg10
  84. #define reg10
  85. #endif
  86. #ifndef reg11
  87. #define reg11
  88. #endif
  89. #ifndef reg12
  90. #define reg12
  91. #endif
  92.  
  93. /*
  94. EXPORT   boolean UNIFY();
  95. EXPORT   boolean INTRES(), LONGRES();
  96. EXPORT  void KILLSTACKS();
  97. EXPORT   ENV NEWENV(int);
  98. EXPORT   ENV ENVTOP;
  99. EXPORT  TRAIL TRAILEND;
  100. EXPORT TERM DEREF();
  101. */
  102.  
  103. IMPORT TERM HEAPTOP; /* from manager.c */
  104. IMPORT ATOM ATOMSTOP; /* from manager.c */
  105. IMPORT STRING STRINGSTOP;
  106. IMPORT TERM GLOTOP;
  107. IMPORT ENV CHOICEPOINT;
  108. IMPORT boolean OCHECK;
  109. IMPORT void ABORT();      /* from io.c */
  110. IMPORT void reclaim_heap();
  111. FORWARD boolean UNIFY();
  112.  
  113. #if !INLINE
  114. GLOBAL TERM DEREF(register TERM x, register TERM b)
  115. { if(name(x)==UNBOUNDT) 
  116.     { if(is_heapterm(x)) return mkfreevar(); }
  117.   else
  118.     { if(name(x)==SKELT) x=b+offset(x); 
  119.       while(name(x)==VART) x=val(x); 
  120.     }
  121.   return x;
  122. }
  123. #endif
  124.  
  125.  
  126. #if !POINTEROFFSET
  127. GLOBAL TRAIL TRAILEND=trail_units(1);
  128. GLOBAL TRAIL BASETRAIL=trail_units(1);
  129. #define ENDTRAILER MAXTRAILER
  130. #endif
  131.  
  132. #if POINTEROFFSET
  133. #ifdef DYNMEM
  134. GLOBAL TRAIL TRAILEND;
  135. GLOBAL TRAIL BASETRAIL;
  136. GLOBAL TRAIL ENDTRAILER;
  137. #else
  138. GLOBAL TRAIL TRAILEND= &TRAILTAB[1];
  139. GLOBAL TRAIL BASETRAIL= &TRAILTAB[1];
  140. GLOBAL TRAIL ENDTRAILER= &TRAILTAB[MAXTRAILER];
  141. #endif
  142. #endif
  143.  
  144. GLOBAL ENV   ENVTOP=env_units(1);
  145. GLOBAL ENV   BASEENV=env_units(1);
  146.  
  147.  
  148. /*
  149.    Specialized unification algorithm for returning integer results.
  150.    IntResult(x, i) is equivalent to Unify(x, MakeInt(i), ee, 0, 0)
  151.    but avoids allocating a global node.
  152. */
  153.  
  154. GLOBAL boolean INTRES (register TERM X, register int I)
  155.   deref(X);
  156.   if(name(X)==INTT) return ival(X)==I;
  157.   if(name(X)==UNBOUNDT)
  158.      { name(X)=INTT; ival(X)=I; 
  159.        if(X<base(CHOICEPOINT)) 
  160.           { if(TRAILEND >=ENDTRAILER) ABORT(TRAILSPACEE);
  161.             boundvar(TRAILEND)=X; 
  162.             inc_trail(TRAILEND); }
  163.        return true; 
  164.      }
  165.   return false;
  166. }
  167.  
  168.  
  169. #if LONGARITH
  170. GLOBAL boolean LONGRES(TERM T, long L)
  171. {
  172.    if(minint<=L && L<=maxint)
  173.      return INTRES(T,(int)L);
  174.    else return UNI(T,mklong(L));
  175. }
  176. #endif
  177. /*
  178.  
  179. The abstract Prolog machine contains two stacks, the local stack and
  180. the global stack.  The local stack is held in the global array
  181. 'display', with local variables in the global array 'locstack'.  These
  182. arrays have stack pointers 'envtop' and 'loctop' respectively.  The
  183. global stack is held as a chain of nodes starting at 'glotop'.
  184.  
  185. */
  186.  
  187. /* Create a new environment e. */
  188.  
  189. /*
  190.    Do not alterate Newenv
  191.    Newenv is used in execute as inline-code
  192.  */
  193. GLOBAL ENV NEWENV (REGISTER int VAR_SIZES)
  194. { register ENV EP; register TERM T;
  195.   if((EP=ENVTOP)>=MAXENVS) ABORT(FRAMESPACEE);
  196.   inc_env(ENVTOP);
  197.   choice(EP)=CHOICEPOINT;
  198.   trail(EP)=TRAILEND;
  199.   atomtop(EP)=ATOMSTOP;
  200.   base(EP)=T=GLOTOP;
  201.   if((GLOTOP+=(unsigned)VAR_SIZES) >=HEAPTOP) reclaim_heap(true);
  202.   while(dec_term(VAR_SIZES)>=0)
  203.     { name(T)=UNBOUNDT; inc_term(T); } 
  204.   return EP;
  205. }
  206.  
  207.  
  208. /*
  209.    Dispose of all environments after newtop, together with all
  210.    associated global storage, and undo critical variable bindings.
  211.    Do not alterate Killstacks
  212.    Killstacks is used in execute as inline-code
  213.  */
  214. GLOBAL void KILLSTACKS (register ENV N)
  215. { if(ENVTOP>=N)
  216.     { register TRAIL  Q,QQ; 
  217.       CHOICEPOINT=choice(N);
  218.       ATOMSTOP=atomtop(N);
  219.       STRINGSTOP= (STRING)nextatom(ATOMSTOP);
  220.       GLOTOP=base(N);
  221.       ENVTOP=N;
  222.       Q=TRAILEND; TRAILEND=QQ=trail(N);
  223.       while(QQ<Q) 
  224.         { name(boundvar(QQ))=UNBOUNDT; inc_trail(QQ); }
  225.     }
  226. }
  227.  
  228. /* 
  229. Unify implements the unification algorithm, which finds the most
  230. general common instance of a pair of terms. It performs the matching
  231. substitution by introducing variable bindings.  The occur check
  232. is executed only if the corresponding flag is set.
  233. */
  234.  
  235. #if OCCUR_CHECK
  236. LOCAL boolean O_Check(reg3 int N, reg5 TERM V, reg4 TERM T, 
  237.                       reg6 TERM BT, int DEPTH)
  238. { /* returns true, if V is an element of T */
  239.   reg1 TERM S=T; 
  240.   reg2 ATOM A;
  241.   if(N==0) return false;
  242.   if(DEPTH==0)ABORT(DEPTHE);
  243.   for(;;)
  244.   {  
  245.     if(name(S)==SKELT) S=BT+offset(S); 
  246.     while(name(S)==VART) S=val(S);
  247.     if(name(S)==UNBOUNDT) return (S==V);
  248.     if(O_Check(arity(name(S)),V,son(S),BT,DEPTH-1)) return true; 
  249.     if(--N==0) break;
  250.     S=next_br(T);
  251.   } 
  252.   return false;
  253. }
  254. #endif
  255.  
  256.  
  257. /* 
  258.    BIND creates a copy of the given argument list X on the stack
  259.    N - length of argument list;
  260.    X - pointer to first argument (X is assumed to be on heap);
  261.    B - base of the current environment for X;
  262. */
  263.  
  264. #define bindspace(N) \
  265.                { if((GLOTOP+=term_units(N))>=HEAPTOP) reclaim_heap(true); }
  266.  
  267. LOCAL TERM BIND( reg6 int N, reg2 TERM X, reg4 TERM B)
  268. {
  269.   reg2 TERM Y;
  270.   reg4 TERM T;
  271.   T=Y=GLOTOP;
  272. bind_top:
  273.   bindspace(N);
  274.  
  275.   for(;;)
  276.     if(name(X)==SKELT) 
  277.     { reg6 TERM S;
  278.       S=B+offset(X);
  279.       while(name(S)==VART) S=val(S); 
  280.       name(Y)=VART; val(Y)=S;
  281.       if(--N==0)goto ret;
  282.       next_br(X);next_br(Y);continue;
  283.     }
  284.     else 
  285.     { reg6 int S;
  286.       if(S=arity(name(Y)=name(X)))
  287.         { if(--N !=0) son(Y)=BIND(S,son(X),B);
  288.           else { N=S;Y=son(Y)=GLOTOP; X=son(X); goto bind_top; }
  289.           next_br(Y);next_br(X); continue;
  290.         }
  291.       else val(Y)=val(X);
  292.       if(--N==0)goto ret;
  293.       next_br(X);next_br(Y);continue;
  294.     }
  295.  ret: return T;
  296. }
  297.  
  298. /* Unify x1 and x2.  Perform the matching substitution
  299.    by binding variables. */
  300. #if ! INLINE
  301. GLOBAL boolean UNI(TERM Y1, TERM Y2)
  302. { return UNIFY(1,Y1,Y2,BE,BE,MAXDEPTH); }
  303. #endif
  304.  
  305.  
  306.  
  307. GLOBAL boolean UNIFY (int N, TERM Y1, TERM Y2, TERM B1, TERM B2, 
  308.                       int DEPTH)
  309. { reg1 TERM X1=Y1; reg2 TERM X2=Y2; 
  310.   reg4 ATOM A1; reg3 ATOM A2; reg5 TERM BC; 
  311.   TERM TOP; TRAIL TEND; card TAILRECUR=DEPTH; 
  312.  
  313. #define trailing(v,h)        {if(v<BC) { boundvar(TRAILEND)=v;\
  314.               if(inc_trail(TRAILEND)>=ENDTRAILER) ABORT(TRAILSPACEE);}}
  315. #define dereferencing(x,b) {if(name(x)==SKELT) x=b+offset(x);\
  316.                       while(name(x)==VART) x=val(x);}
  317. #define varbind(x,y)       { if(x<y)\
  318.         {name(y)=VART; val(y)=x; trailing(y,A1); }\
  319.         else { if(heap_term(x)) goto nextbrother;\
  320.           else if(x>y) {name(x)=VART;val(x)=y; trailing(x,A1);}}}
  321. #undef  annontvar
  322. #define annontvar          heap_term
  323. #if OCCUR_CHECK
  324. #define occurcheck(ar,v,t,b){if(OCHECK && \
  325.                       O_Check(ar,v,son(t),b,MAXDEPTH))goto failure;}
  326. #define occur1check(n,v,t,b){if(OCHECK && arity(n))\
  327.                  if(O_Check(arity(n),v,son(t),b,MAXDEPTH))goto failure;}
  328. #endif
  329. #if !OCCUR_CHECK
  330. #define occurcheck(ar,v,t,b)
  331. #define occur1check(n,v,t,b)
  332. #endif
  333. #define heap_term(x)  (x>GLOTOP)
  334. #define stack_term(x) (x<=GLOTOP)
  335.  
  336.   if(DEPTH==0) ABORT(DEPTHE);
  337.   TEND=TRAILEND;
  338.   TOP=GLOTOP;
  339.   BC=base(CHOICEPOINT); 
  340. deref_top:   
  341.   for(;;)
  342.     { A2=name(X2);
  343.       
  344.       if(A2>FUNCNAME)
  345.         { dereferencing(X1,B1); 
  346.           if((A1=name(X1))!=A2) 
  347.             { if(A1==UNBOUNDT) 
  348.                 { if(annontvar(X1)) goto nextbrother;
  349.                   trailing(X1,A1); 
  350.                   if(A1=arity(A2)) goto func3; 
  351.                   name(X1)=A2;son(X1)=nil_term;goto nextbrother;}
  352.               goto failure;
  353.             }
  354.           if(A1=arity(A2)) goto func4;
  355.           goto nextbrother;
  356.         } 
  357.       if(A2==SKELT)
  358.         { X2=B2+offset(X2); 
  359.           if((A2=name(X2))==UNBOUNDT) goto unboundt2;
  360.           else if(A2 !=VART) goto func2;
  361.           goto vart2;
  362.         }
  363.       if(A2==UNBOUNDT) 
  364.         { if(annontvar(X2)) goto nextbrother; 
  365.           goto unboundt2;
  366.         }
  367.       if(A2==VART) 
  368.         { vart2: 
  369.           do X2=val(X2);while(name(X2)==VART);
  370.           A2=name(X2); 
  371.         }
  372.       if(A2==UNBOUNDT) 
  373.         { unboundt2: dereferencing(X1,B1); 
  374.           if((A1=name(X1))>FUNCNAME)
  375.             { trailing(X2,A2);
  376.               if(stack_term(X1))
  377.                 { occur1check(A1,X2,X1,B1);
  378.                   name(X2)=A1; son(X2)=son(X1);
  379.                 }
  380.               else if(A2=arity(A1))
  381.                 { occurcheck((int)A2,X2,X1,B1);
  382.                   name(X2)=A1; 
  383.                 bind1:
  384.                   X2=son(X2)=GLOTOP;
  385.                   X1=son(X1);
  386.                   bindspace(A2);
  387.                   for(;;)
  388.                     { if(name(X1)==SKELT) 
  389.                         { register TERM X;
  390.                           X=B1+offset(X1); 
  391.                           while(name(X)==VART) X=val(X);
  392.                           name(X2)=VART;val(X2)=X; 
  393.                           if(--A2==0) break;
  394.                           next_br(X1); next_br(X2);continue;
  395.                         }
  396.                       name(X2)=A1=name(X1); 
  397.                       if(--A2==0)
  398.                         { 
  399.                           if(A1==INTT) { ival(X2)=ival(X1);break;}
  400.                           if(A2=arity(A1)) goto bind1; 
  401.                           else son(X2)=nil_term;
  402.                           break;
  403.                         }
  404.                       else
  405.                         { if(A1=arity(A1))
  406.                             { son(X2)=BIND((int)A1,son(X1),B1);}
  407.                           else val(X2)=val(X1);
  408.                           next_br(X1);next_br(X2);
  409.                         }
  410.                     }
  411.                 }
  412.               else { name(X2)=A1; son(X2)=nil_term; }
  413.             } 
  414.           else if(A1!=A2)
  415.             {name(X2)=A1;ival(X2)=A1=ival(X1);trailing(X2,A2);}
  416.           else /* A1==UNBOUNDT */
  417.               varbind(X1,X2)
  418.         }
  419.       else 
  420.         { func2: dereferencing(X1,B1); 
  421.           if((A1=name(X1))!=A2) 
  422.             if(A1==UNBOUNDT)
  423.               { if(annontvar(X1)) goto nextbrother;
  424.                 trailing(X1,A1);
  425.                 if(A1=arity(A2))
  426.                   { func3: 
  427.                     occurcheck((int)A1,X1,X2,B2);
  428.                     name(X1)=A2;
  429.                     if(X2>GLOTOP)   /* heap_term */
  430.                       { bind2:
  431.                         X1=son(X1)=GLOTOP;
  432.                         X2=son(X2);
  433.                         bindspace(A1);
  434.                         for(;;)
  435.                           { if(name(X2)==SKELT) 
  436.                               { register TERM X;
  437.                                 X=B2+offset(X2); 
  438.                                 while(name(X)==VART) X=val(X);
  439.                                 name(X1)=VART;val(X1)=X;
  440.                                 if(--A1==0) break;
  441.                                 next_br(X1); next_br(X2);continue;
  442.                               }
  443.                             name(X1)=A2=name(X2);
  444.                             if(A2=arity(A2))
  445.                               { if(--A1 !=0)
  446.                                   { son(X1)=BIND((int)A2,son(X2),B2);
  447.                                     next_br(X1);next_br(X2); 
  448.                                     continue;
  449.                                   }
  450.                                 else
  451.                                   { A1=A2; goto bind2;}
  452.                               }
  453.                             val(X1)=val(X2);
  454.                             if(--A1==0) break;
  455.                             next_br(X1); next_br(X2);continue;
  456.                           }
  457.                       }
  458.                     else son(X1)=son(X2);
  459.                   }
  460.                 else  {  name(X1)=A2; val(X1)=val(X2);  }
  461.               } 
  462.             else goto failure;
  463.           else if(A1=arity(A2))
  464.             {func4:  
  465.               if(--N==0)
  466.                { N=A1; Y1=X1=son(X1);Y2=X2=son(X2);
  467.                  if(++TAILRECUR!=0) goto deref_top;
  468.                  ABORT(DEPTHE);
  469.                }        
  470.               if(!UNIFY((int)A1,son(X1),son(X2),B1,B2,DEPTH-1))
  471.                       goto failure;
  472.               X1=next_br(Y1); X2=next_br(Y2); continue;
  473.             }
  474.           else 
  475.             if(val(X1)!=val(X2)) goto failure;
  476.        }
  477. nextbrother:     
  478.     if(--N==0) goto success;
  479.     X1=next_br(Y1); X2=next_br(Y2);continue;
  480.   }
  481.   
  482. failure:        
  483.   GLOTOP=TOP; 
  484.   while(TEND<TRAILEND)
  485.    { X1=boundvar(dec_trail(TRAILEND)); name(X1)=UNBOUNDT;}
  486.   return false;
  487.  
  488. success: 
  489.   return true;
  490. }
  491.  
  492.  
  493.